package com.pktechan.manage.service.impl;

import com.pktechan.manage.base.BaseMapper;
import com.pktechan.manage.base.BaseServiceImpl;
import com.pktechan.manage.dao.*;
import com.pktechan.manage.entity.*;
import com.pktechan.manage.exception.CustomException;
import com.pktechan.manage.service.SysRoleService;
import com.pktechan.manage.vo.RoleOperateListVO;
import com.pktechan.manage.vo.SysUserVO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Service("sysRoleService")
public class SysRoleServiceImpl extends BaseServiceImpl<SysRole> implements SysRoleService {
    private static final Logger logger = LoggerFactory.getLogger(SysRoleServiceImpl.class);

    @Autowired
    private SysRoleMapper sysRoleMapper;
    @Autowired
    private SysUserRoleMapMapper sysUserRoleMapMapper;
    @Autowired
    private SysRoleOperateMapMapper sysRoleOperateMapMapper;
    @Autowired
    private SysOperateMapper sysOperateMapper;
    @Autowired
    private SysUserMapper sysUserMapper;

    /**
     * 由业务类实现
     *
     * @return
     */
    @Override
    public BaseMapper<SysRole> getBaseMapper() {
        return sysRoleMapper;
    }

    @Override
    public void deleteSystemRole(Integer id) {
        logger.debug("删除指定的角色关系信息");

        // 验证员工的唯一性。
        SysRole role = (SysRole) sysRoleMapper.getById(id);
        if (role != null) {
            // 验证是否存在关联关系。
            List<SysUserRoleMap> list = sysUserRoleMapMapper.queryListByRole(role.getId());

            if (list.size() > 0) {
                // 有关联关系的对象存在
                throw new CustomException("当前角色已绑定用户");
            } else {
                // 权限关系解绑。
                unBindingAllOperatesByRole(id);
                // 删除角色。
                sysRoleMapper.deleteById(id);
            }
        } else {
            // 不存在。
            throw new CustomException("角色不存在");
        }
    }

    /**
     * 解除指定角色下所有权限的绑定关系。
     *
     * @param roleId
     *            指定的角色唯一标识。
     */
    private void unBindingAllOperatesByRole(Integer roleId) {
        logger.debug("解除指定角色下所有权限的绑定关系");
        try {
            sysRoleOperateMapMapper.deleteById(roleId);
        } catch (Exception e) {
            throw new CustomException("解除权限绑定关系失败，具体原因请参考：" + e.getMessage());
        }
    }

    /**
     * 添加角色信息列表。
     * @param roleOperateListEntity
     * @return
     */
    @Override
    public SysRole addAndBindingOperate(RoleOperateListVO roleOperateListEntity) {
        logger.debug("新增角色及绑定权限关系");
        SysRole flag = new SysRole();
        SysRole roleEntity = roleOperateListEntity.getRole();
        if (roleEntity == null) {
            logger.warn("添加指定的角色错误，角色不能为空。");
            throw new CustomException("添加指定的角色错误，角色不能为空。");
        } else {
            flag = addSystemRole(roleEntity);
            SysRole role;
            try {
                role = sysRoleMapper.queryByName(roleEntity);
            } catch (Exception e) {
                throw new CustomException("角色已存在");
            }
            roleOperateListEntity.setRole(role);
            bindingRoleOperate(roleOperateListEntity);
        }
        return flag;
    }


    /**
     * 添加指定的角色关系信息。
     * TA清算
     * @param sysRole
     *            指定的角色关系信息。
     */
    public SysRole addSystemRole(SysRole sysRole) {
        logger.debug("添加指定的角色关系信息");

        boolean exist = validatExistByRoleName(sysRole.getName());
        if (exist) {
            throw new CustomException("用户名已存在！");
        } else {
            // 不存在，添加。
            sysRoleMapper.save(sysRole);
            return sysRole;
        }
    }
    /**
     * 验证指定的角色是否存在。（验证角色名称是否重复）
     *
     * @param p_name
     *            指定的角色信息。
     * @return
     * @throws Exception
     */
    private boolean validatExistByRoleName(String p_name) {
        logger.debug("验证指定的角色是否存在");

        SysRole role = new SysRole();
        role.setName(p_name);
        int count = sysRoleMapper.validateExistByRole(role);
        if (count > 0) {
            return true;
        }

        return false;
    }
    /**
     * 绑定角色与权限的关联关系。
     *
     * @param roleOperateListEntity
     *            角色权限关联列表
     */
    private void bindingRoleOperate(RoleOperateListVO roleOperateListEntity) {
        logger.debug("绑定角色与权限的关联关系");
        try {
            Integer roleId = roleOperateListEntity.getRole().getId();
            List<Integer> operateList = roleOperateListEntity.getOperates();
            if(!operateList.isEmpty()){
                for (Integer operateId : operateList) {
                    SysRoleOperateMap sysRoleOperateMap = new SysRoleOperateMap();
                    sysRoleOperateMap.setRoleId(roleId);
                    sysRoleOperateMap.setOperateId(operateId);
                    sysRoleOperateMapMapper.save(sysRoleOperateMap);
                }
            }
        } catch (Exception e) {
            throw new CustomException("绑定角色权限关系失败，具体原因请参考：" + e.getMessage());
        }
    }

    /**
     * 查询全部角色权限
     * @return
     */
    @Override
    public List<SysOperate> queryOperateListByRoleId() {
        return sysOperateMapper.queryAllOperateList();
    }

    /**
     * 查看角色相关员工列表。
     * @param sysRole
     * @return
     */
    @Override
    public List<SysUser> getOaStaffsByRoleId(SysRole sysRole) {
        return sysOperateMapper.getOaStaffsByRoleId(sysRole);
    }

    /**
     * 更新角色信息列表。
     * @param roleOperateListEntity
     */
    @Override
    public void updateSystemRole(RoleOperateListVO roleOperateListEntity) {
        logger.debug("更新指定的角色关系信息");

        SysRole role = roleOperateListEntity.getRole();

        // 验证员工的唯一性。
        Integer count = sysRoleMapper.validateExistByRole(role);

        if (count > 0) {
            // 验证名称和类型是否存在。
            SysRole sysRole = sysRoleMapper.queryByName(role);

            if (sysRole != null) {
                if (sysRole.getId().intValue() != role.getId().intValue()) {
                    // 存在重复的角色，不能修改。
                    throw new CustomException("存在重复的角色，不能修改");
                }
            }
            // 存在，更新。
            sysRoleMapper.update(role);
        } else {
            // 不存在。
            throw new CustomException("员工不存在");
        }
        // 权限关系解绑。
        unBindingAllOperatesByRole(role.getId());

        // 重新绑定权限关系。
        try {
            List<Integer> operates = roleOperateListEntity.getOperates();
            for (Integer operateId : operates) {
                SysRoleOperateMap linker = new SysRoleOperateMap();
                linker.setRoleId(role.getId());
                linker.setOperateId(operateId);
                sysRoleOperateMapMapper.save(linker);
            }
        } catch (Exception e) {
            throw new CustomException("绑定权限关系失败，具体原因请参考：" + e.getMessage());
        }
    }

    /**
     * 根据指定唯一标识获取角色信息
     * @param roleId
     * @return
     */
    @Override
    public RoleOperateListVO getRoleOperatesById(Integer roleId) {
        logger.debug("根据指定唯一标识获取角色信息");

        try {
            SysRole role = (SysRole) sysRoleMapper.getById(roleId);
            List<SysRoleOperateMap> list = sysRoleOperateMapMapper.queryListByRole(roleId);
            List<Integer> operates = new ArrayList<Integer>();
            for (SysRoleOperateMap roleOperate : list) {
                operates.add(roleOperate.getOperateId());
            }

            RoleOperateListVO roleOperateListVO = new RoleOperateListVO(role, operates);
            return roleOperateListVO;
        } catch (Exception e) {
            throw new CustomException("获取指定角色权限关联失败，具体原因请参考：" + e.getMessage());
        }
    }

    /**
     * 根据角色id 查询具体权限信息
     * @param roleOperateListVO
     * @return
     */
    @Override
    public Map queryListByTypeAndRoleId(RoleOperateListVO roleOperateListVO) {
//        SysOperate sysOperate = new SysOperate();
//        sysOperate.setRoleId(userRole.getRole().getId());
        List<SysOperate> list = sysOperateMapper.queryAllOperateList();
        List<SysOperate> listByType = sysOperateMapper.queryAllOperateListByType(1);
        Map map = new HashMap();
        map.put("roleId",roleOperateListVO.getRole().getId());
        map.put("name",roleOperateListVO.getRole().getName());
        map.put("operates",roleOperateListVO.getOperates());
        map.put("list",list);
        map.put("listByType",listByType);
        return map;
    }

    /**
     * 解除用户下的所有角色绑定。
     * @param userId
     */
    @Override
    public void deleteAllRoleByUser(Integer userId) throws Exception{
        logger.debug("解除人员在指定门店下的所有角色绑定");

        // 确认用户存在。
        SysUser userEntity = (SysUser) sysUserMapper.getById(userId);
        if (userEntity == null) {
            throw new CustomException("员工不存在");
        }
        logger.debug("绑定人员在指定的角色列表");
        try {
            sysUserRoleMapMapper.deleteById(userId);
        } catch (Exception e) {
            throw new CustomException("解除人员角色绑定失败，具体原因请参考：" + e.getMessage());
        }
    }

    /**
     * 更新人员与角色关联关系。
     * @param user
     */
    @Override
    public void updateUserRole(SysUserVO user) throws Exception {
        logger.debug("更新人员与角色关联关系");
        // 全部解绑。
        unBindingAllRoleByUser(user.getId());
        // 绑定。
        bindingUserRole(user.getId(), user.getRoles());
    }
    /**
     * 绑定人员在指定的角色列表。
     * TA清算
     * @param userId
     *            人员。
     */
    private void unBindingAllRoleByUser(Integer userId) throws Exception {
        logger.debug("绑定人员在指定的角色列表");
        try {
            sysUserRoleMapMapper.deleteById(userId);
        } catch (Exception e) {
            throw new CustomException("解除人员角色绑定失败，具体原因请参考：" + e.getMessage());
        }
    }

    /**
     * 绑定人员在指定的角色列表。
     * TA清算
     * @param userId
     *            人员。
     * @param roleList
     *            角色列表。
     */
    private void bindingUserRole(Integer userId, List<Integer> roleList) throws Exception {
        logger.debug("绑定人员在指定的角色列表");

        try {
            for (Integer roleId : roleList) {
                SysUserRoleMap sysUserRoleMap = new SysUserRoleMap(userId, roleId);
                sysUserRoleMapMapper.save(sysUserRoleMap);
            }
        } catch (Exception e) {
            throw new CustomException("绑定人员角色失败，具体原因请参考：" + e.getMessage());
        }
    }
}
